package com.xh.bussiness.weixin.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONObject;
import com.xh.bussiness.weixin.service.IWeixinService;
import com.xh.core.properties.WxMaProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Pitt Cheung
 * @date 2021/7/15 15:08
 */
@Service
public class WeixinServiceImpl implements IWeixinService {

    @Autowired
    private WxMaProperties wxMaProperties;
    @Autowired
    private RestTemplate restTemplate;


    @Override
    public String getWeixinToken() {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", wxMaProperties.getConfigs().get(0).getAppid(), wxMaProperties.getConfigs().get(0).getSecret());
        JSONObject forObject = restTemplate.getForObject(url, JSONObject.class);
        return forObject.get("access_token").toString();
    }

    @Override
    public String wxaCode(HttpServletRequest request, String accessToken, String pageUrl, String scene) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpMethod method = HttpMethod.POST;

        Map<String, String> params = new HashMap<>();
        params.put("scene", scene);
        params.put("page", pageUrl);

        HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(params, headers);
        String url = String.format("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s", accessToken);
        ResponseEntity<Resource> exchange = restTemplate.exchange(url, method, requestEntity, Resource.class);
        Resource body = exchange.getBody();
        try {
            System.out.println("------------" + body.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        String uploadPath = request.getSession().getServletContext().getRealPath("/");
        String relativePath = "upload/";
        String fileName = UUID.randomUUID().toString().replace("-", "") + ".jpeg";
        try {
            File saveFile = new File(uploadPath + relativePath, fileName);
            if (!saveFile.getParentFile().exists()) {
                saveFile.getParentFile().mkdirs();
            }
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(saveFile));
            InputStream is = body.getInputStream();
            byte[] buffer = new byte[1024];
            int i = -1;
            while ((i = is.read(buffer)) != -1) {
                out.write(buffer, 0, i);
            }
            out.flush();
            out.close();

            System.out.println("***********"+saveFile.getPath());
            return "/" + relativePath + fileName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String wxTicket(String token) {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi",token);
        JSONObject forObject = restTemplate.getForObject(url, JSONObject.class);
        return forObject.get("ticket").toString();
    }


    @Override
    public Map<String, Object> getWxSignature(String url) {
        String weixinToken = getWeixinToken();
        String ticket = wxTicket(weixinToken);
        //随机字符串
        String nonceStr = createNonceStr();
        //时间戳,10位!!10位!!10位!!
        String timestamp = String.format("%010d", System.currentTimeMillis() / 1000);

        String signature = createSignature(nonceStr, ticket, timestamp, url);

        Map<String, Object> map = new HashMap<>();
        map.put("nonceStr", nonceStr);
        map.put("appId", wxMaProperties.getConfigs().get(0).getAppid());
        map.put("timestamp", timestamp);
        map.put("signature", signature);


        return map;
    }


    //生成随机字符串用的
    private static final String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    /**
     * @Description: XiaoYeUtil.createNonceStr
     * @Author: ChenYao
     * @Param: []
     * @Return: java.lang.String
     * @Version: 1.0
     * @Create: Date Time: 2018/12/7
     * @Update: Date Time: 2018/12/7
     * @see:
     * @Note:创建随机串 自定义个数0 < ? < 32
     */
    public static String createNonceStr() {
        String nonceStr = "";
        for (int i = 0; i < 16; i++) {
            int beginIndex = (int) Math.round(Math.random() * 10);
            nonceStr += str.substring(beginIndex, beginIndex + 1);
        }
        return nonceStr;
    }

    /**
     * @Description: XiaoYeUtil.createSignature
     * @Author: ChenYao
     * @Param: [nocestr, ticket, timestamp, url]
     * @Return: java.lang.String
     * @Version: 1.0
     * @Create: Date Time: 2018/12/7
     * @Update: Date Time: 2018/12/7
     * @see:
     * @Note:数据签名
     */
    public static String createSignature(String nocestr, String ticket, String timestamp, String url) {
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        String s = "jsapi_ticket=" + ticket + "&noncestr=" + nocestr
                + "&timestamp=" + timestamp + "&url=" + url;
        return SHA1(s);
    }
    /**
     * @Description: XiaoYeUtil.SHA1
     * @Author: ChenYao
     * @Param: [decript]
     * @Return: java.lang.String
     * @Version: 1.0
     * @Create: Date Time: 2018/12/9
     * @Update: Date Time: 2018/12/9
     * @see:
     * @Note:加密
     */
    public static String SHA1(String decript) {
        try {
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }


}
